package com.shrct.businessprocess.product.impl;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.shrct.businessprocess.organization.RCEmployee;
import com.shrct.businessprocess.organization.RCEnterprise;
import com.shrct.businessprocess.product.RCCompanyService;
import com.shrct.businessprocess.product.RCCompanyServiceEntry;
import com.shrct.businessprocess.product.RCDerivedFullServiceProductSpecification;
import com.shrct.businessprocess.product.RCFullService;
import com.shrct.businessprocess.product.RCFullServiceProductEntry;
import com.shrct.businessprocess.product.RCIdentifiablePhysicalProductEntry;
import com.shrct.businessprocess.product.RCIdentifiablePhysicalProductEntryDAO;
import com.shrct.businessprocess.product.RCLogicProduct;
import com.shrct.businessprocess.product.RCLogicProductEvent;
import com.shrct.businessprocess.product.RCLogicProductStatus;
import com.shrct.businessprocess.product.RCNormalizerService;
import com.shrct.businessprocess.product.RCProductSpecification;
import com.shrct.businessprocess.product.RCRMABorrowReplacementEvent;
import com.shrct.businessprocess.product.RCRMAChildrenReplacementEvent;
import com.shrct.businessprocess.product.RCRMALendReplacementEvent;
import com.shrct.businessprocess.product.RCRMANormalReplacementEvent;
import com.shrct.businessprocess.product.RCServiceInfo;
import com.shrct.businessprocess.product.RCServiceLevel;
import com.shrct.businessprocess.product.RCServiceResponseTime;
import com.shrct.businessprocess.product.impl.RCCompanyServiceEntryImpl;
import com.shrct.businessprocess.product.impl.RCCompanyServiceImpl;
import com.shrct.businessprocess.product.impl.RCFullServiceImpl;
import com.shrct.businessprocess.product.impl.RCFullServiceProductEntryImpl;
import com.shrct.businessprocess.product.impl.RCIdentifiablePhysicalProductEntryImpl;
import com.shrct.businessprocess.product.impl.RCLogicProductEventImpl;
import com.shrct.businessprocess.product.impl.RCRMABorrowReplacementEventImpl;
import com.shrct.businessprocess.product.impl.RCRMAChildrenReplacementEventImpl;
import com.shrct.businessprocess.product.impl.RCRMALendReplacementEventImpl;
import com.shrct.businessprocess.product.impl.RCRMANormalReplacementEventImpl;
import com.shrct.businessprocess.product.proxy.RCLogicProductProxy;
import com.shrct.businessprocess.project.RCProject;
import com.uniquesoft.uidl.validation.Validates;
import edu.fudan.langlab.domain.security.ISystemUserService;
import edu.fudan.langlab.domain.security.User;
import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import edu.fudan.mylang.utils.DateUtil;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;
import org.springframework.beans.factory.BeanFactory;

@Entity
@DiscriminatorValue("RCLOGICPRODUCT_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rclogicproduct")
public class RCLogicProductImpl extends BaseModelObject implements RCLogicProduct {
  public RCLogicProductImpl() {
    super();
  }
  
  public RCLogicProductImpl(final String projectid) {
    super();
    this.projectid = projectid;
  }
  
  private RCLogicProductStatus Status;
  
  public RCLogicProductStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    Status=RCLogicProductStatus.existing;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCLogicProductEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void __registerFullServiceProduct(final RCFullServiceProductEntry serviceProduct) {
    
  }
  
  public void _registerFullServiceProduct(final RCFullServiceProductEntry serviceProduct) {
    if(Status==RCLogicProductStatus.existing){
    	__registerFullServiceProduct(serviceProduct);
    	getModelObjectLogService().createLog(this,"Status","_registerFullServiceProduct");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCLogicProductEventsManager.class).fire_registerFullServiceProduct(this,serviceProduct);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void __registerCompanyService(final RCCompanyServiceEntry companyService) {
    
  }
  
  public void _registerCompanyService(final RCCompanyServiceEntry companyService) {
    if(Status==RCLogicProductStatus.existing){
    	__registerCompanyService(companyService);
    	getModelObjectLogService().createLog(this,"Status","_registerCompanyService");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCLogicProductEventsManager.class).fire_registerCompanyService(this,companyService);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void __unregisterCompanyService(final RCCompanyServiceEntry companyService) {
    
  }
  
  public void _unregisterCompanyService(final RCCompanyServiceEntry companyService) {
    if(Status==RCLogicProductStatus.existing){
    	__unregisterCompanyService(companyService);
    	getModelObjectLogService().createLog(this,"Status","_unregisterCompanyService");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCLogicProductEventsManager.class).fire_unregisterCompanyService(this,companyService);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void __childrenReplacenebtRMA(final RCRMAChildrenReplacementEvent event) {
    
  }
  
  public void _childrenReplacenebtRMA(final RCRMAChildrenReplacementEvent event) {
    if(Status==RCLogicProductStatus.existing){
    	__childrenReplacenebtRMA(event);
    	getModelObjectLogService().createLog(this,"Status","_childrenReplacenebtRMA");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCLogicProductEventsManager.class).fire_childrenReplacenebtRMA(this,event);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void __borrowReplacementRMA(final RCRMABorrowReplacementEvent event) {
    
  }
  
  public void _borrowReplacementRMA(final RCRMABorrowReplacementEvent event) {
    if(Status==RCLogicProductStatus.existing){
    	__borrowReplacementRMA(event);
    	getModelObjectLogService().createLog(this,"Status","_borrowReplacementRMA");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCLogicProductEventsManager.class).fire_borrowReplacementRMA(this,event);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void __normalRMA(final RCRMANormalReplacementEvent event) {
    
  }
  
  public void _normalRMA(final RCRMANormalReplacementEvent event) {
    if(Status==RCLogicProductStatus.existing){
    	__normalRMA(event);
    	getModelObjectLogService().createLog(this,"Status","_normalRMA");
    	getBeanFactory().getBean(com.shrct.businessprocess.product.events.RCLogicProductEventsManager.class).fire_normalRMA(this,event);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isExisting() {
    return com.shrct.businessprocess.product.RCLogicProductStatus.existing==Status;
  }
  
  private String projectid;
  
  public String getProjectid() {
    return this.projectid;
  }
  
  public RCLogicProduct setProjectid(final String projectid) {
    this.projectid = projectid;
    return this;			
    
  }
  
  @JoinColumn(name = "currentProduct_id")
  @ManyToOne(targetEntity = RCIdentifiablePhysicalProductEntryImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCIdentifiablePhysicalProductEntry currentProduct;
  
  public RCIdentifiablePhysicalProductEntry getCurrentProduct() {
    return this.currentProduct;
  }
  
  public RCLogicProduct setCurrentProduct(final RCIdentifiablePhysicalProductEntry currentProduct) {
    this.currentProduct = currentProduct;
    return this;			
    
  }
  
  @JoinColumn(name = "currentProductService_id")
  @ManyToOne(targetEntity = RCFullServiceProductEntryImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCFullServiceProductEntry currentProductService;
  
  public RCFullServiceProductEntry getCurrentProductService() {
    return this.currentProductService;
  }
  
  public RCLogicProduct setCurrentProductService(final RCFullServiceProductEntry currentProductService) {
    this.currentProductService = currentProductService;
    return this;			
    
  }
  
  @JoinColumn(name = "currentCompanyService_id")
  @ManyToOne(targetEntity = RCCompanyServiceEntryImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCCompanyServiceEntry currentCompanyService;
  
  public RCCompanyServiceEntry getCurrentCompanyService() {
    return this.currentCompanyService;
  }
  
  public RCLogicProduct setCurrentCompanyService(final RCCompanyServiceEntry currentCompanyService) {
    this.currentCompanyService = currentCompanyService;
    return this;			
    
  }
  
  private Boolean requireService = Boolean.valueOf(true);
  
  public Boolean getRequireService() {
    return this.requireService;
  }
  
  public RCLogicProduct setRequireService(final Boolean requireService) {
    this.requireService = requireService;
    return this;			
    
  }
  
  @OneToMany(targetEntity = RCLogicProductEventImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "logicProduct")
  private Collection<RCLogicProductEvent> trans = new java.util.ArrayList<com.shrct.businessprocess.product.RCLogicProductEvent>();;
  
  public Collection<RCLogicProductEvent> getTrans() {
    return this.trans;
  }
  
  public RCLogicProduct removeAllTrans() {
    for(RCLogicProductEvent obj : this.trans){
    	getObjectFactory().delete(obj);
    }
    this.trans.clear();
    return this;	
    
  }
  
  public RCLogicProduct removeFromTrans(final RCLogicProductEvent rCLogicProductEvent) {
    this.trans.remove(rCLogicProductEvent);
    getObjectFactory().delete(rCLogicProductEvent);
    return this;
    
  }
  
  @OneToMany(targetEntity = RCCompanyServiceImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "logicProduct")
  private Collection<RCCompanyService> companyServices = new java.util.ArrayList<com.shrct.businessprocess.product.RCCompanyService>();;
  
  public Collection<RCCompanyService> getCompanyServices() {
    return this.companyServices;
  }
  
  public RCCompanyService createAndAddtoCompanyServices() {
    getCompanyServices().size();
    com.shrct.businessprocess.product.RCCompanyService rCCompanyService = new com.shrct.businessprocess.product.impl.RCCompanyServiceImpl(this);
    getObjectFactory().create(rCCompanyService);
    getCompanyServices().add(rCCompanyService);
    return rCCompanyService;
    
  }
  
  public RCCompanyService createAndAddtoCompanyServices(final Procedure1<RCCompanyService> updater) {
    getCompanyServices().size();
    com.shrct.businessprocess.product.RCCompanyService rCCompanyService = new com.shrct.businessprocess.product.impl.RCCompanyServiceImpl(this);
    getObjectFactory().create(rCCompanyService);
    getCompanyServices().add(rCCompanyService);
    return rCCompanyService;
    
  }
  
  public RCLogicProduct removeAllCompanyServices() {
    for(RCCompanyService obj : this.companyServices){
    	getObjectFactory().delete(obj);
    }
    this.companyServices.clear();
    return this;	
    
  }
  
  public RCLogicProduct removeFromCompanyServices(final RCCompanyService rCCompanyService) {
    this.companyServices.remove(rCCompanyService);
    getObjectFactory().delete(rCCompanyService);
    return this;
    
  }
  
  @OneToMany(targetEntity = RCFullServiceImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "sourceProduct")
  private Collection<RCFullService> fullServices = new java.util.ArrayList<com.shrct.businessprocess.product.RCFullService>();;
  
  public Collection<RCFullService> getFullServices() {
    return this.fullServices;
  }
  
  public RCFullService createAndAddtoFullServices() {
    getFullServices().size();
    com.shrct.businessprocess.product.RCFullService rCFullService = new com.shrct.businessprocess.product.impl.RCFullServiceImpl(this);
    getObjectFactory().create(rCFullService);
    getFullServices().add(rCFullService);
    return rCFullService;
    
  }
  
  public RCFullService createAndAddtoFullServices(final Procedure1<RCFullService> updater) {
    getFullServices().size();
    com.shrct.businessprocess.product.RCFullService rCFullService = new com.shrct.businessprocess.product.impl.RCFullServiceImpl(this);
    getObjectFactory().create(rCFullService);
    getFullServices().add(rCFullService);
    return rCFullService;
    
  }
  
  public RCLogicProduct removeAllFullServices() {
    for(RCFullService obj : this.fullServices){
    	getObjectFactory().delete(obj);
    }
    this.fullServices.clear();
    return this;	
    
  }
  
  public RCLogicProduct removeFromFullServices(final RCFullService rCFullService) {
    this.fullServices.remove(rCFullService);
    getObjectFactory().delete(rCFullService);
    return this;
    
  }
  
  public RCEmployee getSales() {
    RCEmployee _xblockexpression = null;
    {
      IGenericQuery<RCProject> query=getObjectFactory().createGenericQuery(RCProject.class,"select e from com.shrct.businessprocess.project.impl.RCProjectImpl as e   where ((e.code) = (:projectid)) and  e.active = 1      ").setParameter("projectid",projectid);
      final RCProject p = query.uniqueResult();
      RCEmployee _majorSales = p==null?(RCEmployee)null:p.getMajorSales();
      _xblockexpression = (_majorSales);
    }
    return _xblockexpression;
  }
  
  public RCIdentifiablePhysicalProductEntryDAO getRCIdentifiablePhysicalProductEntryDAO() {
    BeanFactory _beanFactory = this.getBeanFactory();
    RCIdentifiablePhysicalProductEntryDAO _bean = _beanFactory.<RCIdentifiablePhysicalProductEntryDAO>getBean(RCIdentifiablePhysicalProductEntryDAO.class);
    return _bean;
  }
  
  public User getSystemUser() {
    BeanFactory _beanFactory = this.getBeanFactory();
    ISystemUserService _bean = _beanFactory.<ISystemUserService>getBean(ISystemUserService.class);
    User _currentUser = _bean.getCurrentUser();
    return _currentUser;
  }
  
  public RCNormalizerService getNormalizerService() {
    BeanFactory _beanFactory = this.getBeanFactory();
    RCNormalizerService _bean = _beanFactory.<RCNormalizerService>getBean(RCNormalizerService.class);
    return _bean;
  }
  
  public Collection<RCIdentifiablePhysicalProductEntry> getAllProducts() {
    IGenericQuery<RCIdentifiablePhysicalProductEntry> query=getObjectFactory().createGenericQuery(RCIdentifiablePhysicalProductEntry.class,"select e from com.shrct.businessprocess.product.impl.RCIdentifiablePhysicalProductEntryImpl as e   where ((e.logicProduct) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Collection<RCIdentifiablePhysicalProductEntry> _list = query.list();
    return _list;
  }
  
  /**
   * 更新默认产品服务
   */
  public RCFullServiceProductEntry registerFullServiceProduct(final String _name, final String projectid, final String serviceContraceCode, final RCDerivedFullServiceProductSpecification type, final Date startDate, final Date dueDate) {
    RCFullServiceProductEntry _xblockexpression = null;
    {
      boolean _notEquals = (!Objects.equal(projectid, null));
      Validates.Assert(_notEquals, "\u65E0\u6548\u9879\u76EE\u7F16\u53F7");
      boolean _notEquals_1 = (!Objects.equal(type, null));
      Validates.Assert(_notEquals_1, "\u670D\u52A1\u7F16\u53F7\u4E0D\u80FD\u4E3A\u7A7A");
      boolean _notEquals_2 = (!Objects.equal(startDate, null));
      Validates.Assert(_notEquals_2, "\u670D\u52A1\u5F00\u59CB\u65E5\u671F\u4E0D\u80FD\u4E3A\u7A7A");
      boolean _notEquals_3 = (!Objects.equal(dueDate, null));
      Validates.Assert(_notEquals_3, "\u670D\u52A1\u7ED3\u675F\u65E5\u671F\u4E0D\u80FD\u4E3A\u7A7A");
      final Function1<RCFullService,Boolean> _function = new Function1<RCFullService,Boolean>() {
          public Boolean apply(final RCFullService it) {
            String _name_1 = it.getName();
            boolean _equals = Objects.equal(_name_1, _name);
            return Boolean.valueOf(_equals);
          }
        };
      RCFullService targetFullService = IterableExtensions.<RCFullService>findFirst(this.fullServices, _function);
      boolean _equals = Objects.equal(targetFullService, null);
      if (_equals) {
        RCFullService _createAndAddtoFullServices = this.createAndAddtoFullServices();
        final Procedure1<RCFullService> _function_1 = new Procedure1<RCFullService>() {
            public void apply(final RCFullService it) {
              it.setName(_name);
            }
          };
        RCFullService _doubleArrow = ObjectExtensions.<RCFullService>operator_doubleArrow(_createAndAddtoFullServices, _function_1);
        targetFullService = _doubleArrow;
      }
      RCFullServiceProductEntry _registerFullServiceProduct = targetFullService.registerFullServiceProduct(projectid, serviceContraceCode, type, startDate, dueDate);
      final Procedure1<RCFullServiceProductEntry> _function_2 = new Procedure1<RCFullServiceProductEntry>() {
          public void apply(final RCFullServiceProductEntry it) {
            RCLogicProductImpl.this._registerFullServiceProduct(it);
            RCLogicProductImpl.this.updateProductServiceStatus();
          }
        };
      RCFullServiceProductEntry _doubleArrow_1 = ObjectExtensions.<RCFullServiceProductEntry>operator_doubleArrow(_registerFullServiceProduct, _function_2);
      _xblockexpression = (_doubleArrow_1);
    }
    return _xblockexpression;
  }
  
  public RCCompanyServiceEntry registerCompanyService(final String projectid, final String name, final RCServiceInfo serviceInfo, final Date startDate, final Date dueDate) {
    RCServiceLevel _serviceLevel = serviceInfo.getServiceLevel();
    RCServiceResponseTime _serviceResponseTime = serviceInfo.getServiceResponseTime();
    Integer _monthes = serviceInfo.getMonthes();
    RCCompanyServiceEntry _registerCompanyService = this.registerCompanyService(projectid, name, _serviceLevel, _serviceResponseTime, _monthes, startDate, dueDate);
    return _registerCompanyService;
  }
  
  public RCCompanyServiceEntry registerCompanyService(final String projectid, final String name, final RCServiceLevel serviceLevel, final RCServiceResponseTime serviceResponseTime, final Integer months, final Date startDate, final Date dueDate) {
    RCCompanyServiceEntry _xblockexpression = null;
    {
      boolean _notEquals = (!Objects.equal(projectid, null));
      Validates.Assert(_notEquals, "\u9879\u76EE\u7F16\u53F7\u4E0D\u80FD\u4E3A\u7A7A");
      boolean _notEquals_1 = (!Objects.equal(months, null));
      Validates.Assert(_notEquals_1, "\u670D\u52A1\u6708\u6570\u4E0D\u80FD\u4E3A\u7A7A");
      InputOutput.<String>println("=======>");
      InputOutput.<String>println(name);
      final Procedure1<RCCompanyService> _function = new Procedure1<RCCompanyService>() {
          public void apply(final RCCompanyService it) {
            String _name = it.getName();
            String _plus = ("company service name:" + _name);
            InputOutput.<String>println(_plus);
          }
        };
      IterableExtensions.<RCCompanyService>forEach(this.companyServices, _function);
      final Function1<RCCompanyService,Boolean> _function_1 = new Function1<RCCompanyService,Boolean>() {
          public Boolean apply(final RCCompanyService it) {
            String _name = it.getName();
            boolean _equals = Objects.equal(_name, name);
            return Boolean.valueOf(_equals);
          }
        };
      RCCompanyService companyService = IterableExtensions.<RCCompanyService>findFirst(this.companyServices, _function_1);
      boolean _equals = Objects.equal(companyService, null);
      if (_equals) {
        RCCompanyService _createAndAddtoCompanyServices = this.createAndAddtoCompanyServices();
        final Procedure1<RCCompanyService> _function_2 = new Procedure1<RCCompanyService>() {
            public void apply(final RCCompanyService it) {
              it.setName(name);
            }
          };
        RCCompanyService _doubleArrow = ObjectExtensions.<RCCompanyService>operator_doubleArrow(_createAndAddtoCompanyServices, _function_2);
        companyService = _doubleArrow;
      }
      InputOutput.<String>println("<=======");
      RCCompanyServiceEntry _registerCompanyServiceEntry = companyService.registerCompanyServiceEntry(projectid, startDate, dueDate);
      final Procedure1<RCCompanyServiceEntry> _function_3 = new Procedure1<RCCompanyServiceEntry>() {
          public void apply(final RCCompanyServiceEntry it) {
            RCServiceInfo _serviceInfo = it.getServiceInfo();
            _serviceInfo.setServiceLevel(serviceLevel);
            RCServiceInfo _serviceInfo_1 = it.getServiceInfo();
            _serviceInfo_1.setServiceResponseTime(serviceResponseTime);
            RCServiceInfo _serviceInfo_2 = it.getServiceInfo();
            _serviceInfo_2.setMonthes(months);
            RCLogicProductImpl.this._registerCompanyService(it);
          }
        };
      RCCompanyServiceEntry _doubleArrow_1 = ObjectExtensions.<RCCompanyServiceEntry>operator_doubleArrow(_registerCompanyServiceEntry, _function_3);
      _xblockexpression = (_doubleArrow_1);
    }
    return _xblockexpression;
  }
  
  public void unregisterCompanyService(final RCCompanyServiceEntry entry) {
    RCCompanyService _companyService = entry.getCompanyService();
    _companyService.unregisterCompanyServiceEntry(entry);
  }
  
  public RCRMAChildrenReplacementEvent recordChildrenReplacenebtRMA(final Date date, final String comment, final RCProductSpecification productSpec) {RCRMAChildrenReplacementEvent rCRMAChildrenReplacementEvent=RCRMAChildrenReplacementEventImpl.create(this,getObjectFactory());
    final Procedure1<RCRMAChildrenReplacementEvent> _function = new Procedure1<RCRMAChildrenReplacementEvent>() {
        public void apply(final RCRMAChildrenReplacementEvent it) {
          it.setComment(comment);
          it.setType(productSpec);
          it.setDate(date);
          RCLogicProductImpl.this._childrenReplacenebtRMA(it);
        }
      };
    RCRMAChildrenReplacementEvent _doubleArrow = ObjectExtensions.<RCRMAChildrenReplacementEvent>operator_doubleArrow(rCRMAChildrenReplacementEvent, _function);
    return _doubleArrow;
  }
  
  public RCRMABorrowReplacementEvent recordBorrowReplacementRMA(final Date date, final String sid, final RCIdentifiablePhysicalProductEntry fromProduct) {
    RCRMABorrowReplacementEvent _xblockexpression = null;
    {
      RCIdentifiablePhysicalProductEntryDAO _rCIdentifiablePhysicalProductEntryDAO = this.getRCIdentifiablePhysicalProductEntryDAO();
      final Procedure1<RCIdentifiablePhysicalProductEntry> _function = new Procedure1<RCIdentifiablePhysicalProductEntry>() {
          public void apply(final RCIdentifiablePhysicalProductEntry it) {
            it.setLogicProduct(RCLogicProductImpl.this);
            RCEnterprise _enterprise = RCLogicProductImpl.this.currentProduct.getEnterprise();
            it.setEnterprise(_enterprise);
            RCProductSpecification _type = RCLogicProductImpl.this.currentProduct.getType();
            it.setType(_type);
            String _location = RCLogicProductImpl.this.currentProduct.getLocation();
            it.setLocation(_location);
            it._rmaImport();
          }
        };
      final RCIdentifiablePhysicalProductEntry newProduct = _rCIdentifiablePhysicalProductEntryDAO.create(sid, _function);
      this.currentProduct.setIsReplaced(Boolean.valueOf(true));
      this.currentProduct._rmaReplace();
      fromProduct.setIsBorrowReplaced(Boolean.valueOf(true));RCRMALendReplacementEvent rCRMALendReplacementEvent=RCRMALendReplacementEventImpl.create(this,getObjectFactory());
      final Procedure1<RCRMALendReplacementEvent> _function_1 = new Procedure1<RCRMALendReplacementEvent>() {
          public void apply(final RCRMALendReplacementEvent it) {
            it.setToProduct(newProduct);
            RCLogicProduct _logicProduct = fromProduct.getLogicProduct();
            it.setLogicProduct(_logicProduct);
            it.setDate(date);
            User _systemUser = RCLogicProductImpl.this.getSystemUser();
            it.setOperator(_systemUser);
          }
        };
      ObjectExtensions.<RCRMALendReplacementEvent>operator_doubleArrow(rCRMALendReplacementEvent, _function_1);RCRMABorrowReplacementEvent rCRMABorrowReplacementEvent=RCRMABorrowReplacementEventImpl.create(this,getObjectFactory());
      final Procedure1<RCRMABorrowReplacementEvent> _function_2 = new Procedure1<RCRMABorrowReplacementEvent>() {
          public void apply(final RCRMABorrowReplacementEvent it) {
            it.setFromProduct(fromProduct);
            it.setToProduct(newProduct);
            it.setLogicProduct(RCLogicProductImpl.this);
            it.setDate(date);
            User _systemUser = RCLogicProductImpl.this.getSystemUser();
            it.setOperator(_systemUser);
            RCLogicProductImpl.this._borrowReplacementRMA(it);
          }
        };
      final RCRMABorrowReplacementEvent result = ObjectExtensions.<RCRMABorrowReplacementEvent>operator_doubleArrow(rCRMABorrowReplacementEvent, _function_2);
      this.currentProduct = newProduct;
      _xblockexpression = (result);
    }
    return _xblockexpression;
  }
  
  public RCRMANormalReplacementEvent recordNormalRMA(final Date date, final String sid) {
    RCRMANormalReplacementEvent _xblockexpression = null;
    {
      RCIdentifiablePhysicalProductEntryDAO _rCIdentifiablePhysicalProductEntryDAO = this.getRCIdentifiablePhysicalProductEntryDAO();
      final Procedure1<RCIdentifiablePhysicalProductEntry> _function = new Procedure1<RCIdentifiablePhysicalProductEntry>() {
          public void apply(final RCIdentifiablePhysicalProductEntry it) {
            it.setLogicProduct(RCLogicProductImpl.this);
            RCEnterprise _enterprise = RCLogicProductImpl.this.currentProduct.getEnterprise();
            it.setEnterprise(_enterprise);
            RCProductSpecification _type = RCLogicProductImpl.this.currentProduct.getType();
            it.setType(_type);
            it.setSid(sid);
            RCNormalizerService _normalizerService = RCLogicProductImpl.this.getNormalizerService();
            String _normalizeSid = _normalizerService.normalizeSid(sid);
            it.setNormalizedSid(_normalizeSid);
            String _location = RCLogicProductImpl.this.currentProduct.getLocation();
            it.setLocation(_location);
            it._rmaImport();
          }
        };
      final RCIdentifiablePhysicalProductEntry newProduct = _rCIdentifiablePhysicalProductEntryDAO.create(sid, _function);
      this.currentProduct.setIsReplaced(Boolean.valueOf(true));
      this.currentProduct._rmaReplace();RCRMANormalReplacementEvent rCRMANormalReplacementEvent=RCRMANormalReplacementEventImpl.create(this,getObjectFactory());
      final Procedure1<RCRMANormalReplacementEvent> _function_1 = new Procedure1<RCRMANormalReplacementEvent>() {
          public void apply(final RCRMANormalReplacementEvent it) {
            it.setFromProduct(RCLogicProductImpl.this.currentProduct);
            it.setToProduct(newProduct);
            it.setLogicProduct(RCLogicProductImpl.this);
            it.setDate(date);
            User _systemUser = RCLogicProductImpl.this.getSystemUser();
            it.setOperator(_systemUser);
            RCLogicProductImpl.this._normalRMA(it);
          }
        };
      final RCRMANormalReplacementEvent result = ObjectExtensions.<RCRMANormalReplacementEvent>operator_doubleArrow(rCRMANormalReplacementEvent, _function_1);
      this.currentProduct = newProduct;
      _xblockexpression = (result);
    }
    return _xblockexpression;
  }
  
  public Collection<RCFullServiceProductEntry> getProductServices() {
    final Function1<RCFullService,Collection<RCFullServiceProductEntry>> _function = new Function1<RCFullService,Collection<RCFullServiceProductEntry>>() {
        public Collection<RCFullServiceProductEntry> apply(final RCFullService it) {
          Collection<RCFullServiceProductEntry> _entries = it.getEntries();
          return _entries;
        }
      };
    Iterable<Collection<RCFullServiceProductEntry>> _map = IterableExtensions.<RCFullService, Collection<RCFullServiceProductEntry>>map(this.fullServices, _function);
    Iterable<RCFullServiceProductEntry> _flatten = Iterables.<RCFullServiceProductEntry>concat(_map);
    final Function1<RCFullServiceProductEntry,Date> _function_1 = new Function1<RCFullServiceProductEntry,Date>() {
        public Date apply(final RCFullServiceProductEntry it) {
          Date _start = it.getStart();
          return _start;
        }
      };
    List<RCFullServiceProductEntry> _sortBy = IterableExtensions.<RCFullServiceProductEntry, Date>sortBy(_flatten, _function_1);
    List<RCFullServiceProductEntry> _reverse = ListExtensions.<RCFullServiceProductEntry>reverse(_sortBy);
    List<RCFullServiceProductEntry> _list = IterableExtensions.<RCFullServiceProductEntry>toList(_reverse);
    return _list;
  }
  
  public Collection<RCLogicProductEvent> getEvents() {
    return this.trans;
  }
  
  public String getEntityName() {
    String _sid = this.currentProduct.getSid();
    return _sid;
  }
  
  public RCFullServiceProductEntry getActiveProductService() {
    RCFullServiceProductEntry _xblockexpression = null;
    {
      final Date today = DateUtil.today();
      Collection<RCFullServiceProductEntry> _productServices = this.getProductServices();
      final Function1<RCFullServiceProductEntry,Boolean> _function = new Function1<RCFullServiceProductEntry,Boolean>() {
          public Boolean apply(final RCFullServiceProductEntry it) {
            boolean _and = false;
            Date _start = it.getStart();
            boolean _lessEqualsThan = (_start.compareTo(today) <= 0);
            if (!_lessEqualsThan) {
              _and = false;
            } else {
              Date _end = it.getEnd();
              boolean _greaterEqualsThan = (_end.compareTo(today) >= 0);
              _and = (_lessEqualsThan && _greaterEqualsThan);
            }
            return Boolean.valueOf(_and);
          }
        };
      RCFullServiceProductEntry productService = IterableExtensions.<RCFullServiceProductEntry>findFirst(_productServices, _function);
      boolean _equals = Objects.equal(productService, null);
      if (_equals) {
        Collection<RCFullServiceProductEntry> _productServices_1 = this.getProductServices();
        final Function1<RCFullServiceProductEntry,Boolean> _function_1 = new Function1<RCFullServiceProductEntry,Boolean>() {
            public Boolean apply(final RCFullServiceProductEntry it) {
              Date _start = it.getStart();
              boolean _greaterEqualsThan = (_start.compareTo(today) >= 0);
              return Boolean.valueOf(_greaterEqualsThan);
            }
          };
        RCFullServiceProductEntry _findFirst = IterableExtensions.<RCFullServiceProductEntry>findFirst(_productServices_1, _function_1);
        productService = _findFirst;
      }
      RCFullServiceProductEntry _currentProductService = this.currentProductService = productService;
      _xblockexpression = (_currentProductService);
    }
    return _xblockexpression;
  }
  
  public Iterable<RCCompanyServiceEntry> getCompanyServiceEntries() {
    final Function1<RCCompanyService,Collection<RCCompanyServiceEntry>> _function = new Function1<RCCompanyService,Collection<RCCompanyServiceEntry>>() {
        public Collection<RCCompanyServiceEntry> apply(final RCCompanyService it) {
          Collection<RCCompanyServiceEntry> _entries = it.getEntries();
          return _entries;
        }
      };
    Iterable<Collection<RCCompanyServiceEntry>> _map = IterableExtensions.<RCCompanyService, Collection<RCCompanyServiceEntry>>map(this.companyServices, _function);
    Iterable<RCCompanyServiceEntry> _flatten = Iterables.<RCCompanyServiceEntry>concat(_map);
    return _flatten;
  }
  
  public RCCompanyServiceEntry getActiveCompanyService() {
    RCCompanyServiceEntry _xblockexpression = null;
    {
      final Date today = DateUtil.today();
      Iterable<RCCompanyServiceEntry> _companyServiceEntries = this.getCompanyServiceEntries();
      final Function1<RCCompanyServiceEntry,Boolean> _function = new Function1<RCCompanyServiceEntry,Boolean>() {
          public Boolean apply(final RCCompanyServiceEntry it) {
            boolean _and = false;
            Date _start = it.getStart();
            boolean _lessEqualsThan = (_start.compareTo(today) <= 0);
            if (!_lessEqualsThan) {
              _and = false;
            } else {
              Date _end = it.getEnd();
              boolean _greaterEqualsThan = (_end.compareTo(today) >= 0);
              _and = (_lessEqualsThan && _greaterEqualsThan);
            }
            return Boolean.valueOf(_and);
          }
        };
      RCCompanyServiceEntry companyService = IterableExtensions.<RCCompanyServiceEntry>findFirst(_companyServiceEntries, _function);
      boolean _equals = Objects.equal(companyService, null);
      if (_equals) {
        Iterable<RCCompanyServiceEntry> _companyServiceEntries_1 = this.getCompanyServiceEntries();
        final Function1<RCCompanyServiceEntry,Boolean> _function_1 = new Function1<RCCompanyServiceEntry,Boolean>() {
            public Boolean apply(final RCCompanyServiceEntry it) {
              Date _start = it.getStart();
              boolean _greaterEqualsThan = (_start.compareTo(today) >= 0);
              return Boolean.valueOf(_greaterEqualsThan);
            }
          };
        RCCompanyServiceEntry _findFirst = IterableExtensions.<RCCompanyServiceEntry>findFirst(_companyServiceEntries_1, _function_1);
        companyService = _findFirst;
      }
      _xblockexpression = (companyService);
    }
    return _xblockexpression;
  }
  
  public void updateProductServiceStatus() {
    Collection<RCFullServiceProductEntry> _productServices = this.getProductServices();
    final Function1<RCFullServiceProductEntry,Date> _function = new Function1<RCFullServiceProductEntry,Date>() {
        public Date apply(final RCFullServiceProductEntry it) {
          Date _end = it.getEnd();
          return _end;
        }
      };
    List<RCFullServiceProductEntry> _sortBy = IterableExtensions.<RCFullServiceProductEntry, Date>sortBy(_productServices, _function);
    RCFullServiceProductEntry _last = IterableExtensions.<RCFullServiceProductEntry>last(_sortBy);
    this.currentProductService = _last;
  }
  
  public void updateCompanyServiceStatus() {
    Iterable<RCCompanyServiceEntry> _companyServiceEntries = this.getCompanyServiceEntries();
    final Function1<RCCompanyServiceEntry,Date> _function = new Function1<RCCompanyServiceEntry,Date>() {
        public Date apply(final RCCompanyServiceEntry it) {
          Date _end = it.getEnd();
          return _end;
        }
      };
    List<RCCompanyServiceEntry> _sortBy = IterableExtensions.<RCCompanyServiceEntry, Date>sortBy(_companyServiceEntries, _function);
    RCCompanyServiceEntry _last = IterableExtensions.<RCCompanyServiceEntry>last(_sortBy);
    this.currentCompanyService = _last;
  }
  
  public static RCLogicProduct create(final String projectid, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.product.RCLogicProduct rCLogicProduct = new com.shrct.businessprocess.product.impl.RCLogicProductImpl(
    	projectid
    );
    objectFactory.create(rCLogicProduct);
    return rCLogicProduct;			
    
  }
  
  public static RCLogicProduct createRCLogicProductImpl(final String projectid, final IObjectFactory objectFactory, final Procedure1<RCLogicProduct> init) {
    com.shrct.businessprocess.product.RCLogicProduct rCLogicProduct = new com.shrct.businessprocess.product.impl.RCLogicProductImpl(
    	projectid
    );
    objectFactory.create(rCLogicProduct);
    init.apply(rCLogicProduct);
    
    return rCLogicProduct;			
    
  }
  
  public RCLogicProductProxy toProxy() {
    com.shrct.businessprocess.product.proxy.RCLogicProductProxy proxy = new com.shrct.businessprocess.product.proxy.RCLogicProductProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
